package com.jhws.business.device.api;

import com.alibaba.fastjson.JSON;
import com.jhws.business.aliyun.service.OSSClientService;
import com.jhws.business.appconfig.bo.AppConfigContentInfo;
import com.jhws.business.appconfig.bo.AppConfigInfo;
import com.jhws.business.appconfig.service.AppConfigInfoService;
import com.jhws.business.card.TblCardRecordServiceImpl;
import com.jhws.business.card.bo.*;
import com.jhws.business.comm.bo.TblBuildingDimBo;
import com.jhws.business.comm.bo.TblCommDimBo;
import com.jhws.business.device.bo.*;
import com.jhws.business.device.service.LogDevUnlockService;
import com.jhws.business.local.service.LocalService;
import com.jhws.common.base.bo.JsonRespData;
import com.jhws.core.exception.BizException;
import com.jhws.core.log.bo.LogConstants;
import com.jhws.util.*;

import com.jhws.business.comm.service.ITblBuildingDimService;
import com.jhws.business.card.service.ITblCardDimService;
import com.jhws.business.comm.service.ITblCommDimService;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2017/4/27.
 */
@SuppressWarnings("Duplicates")
@Controller
@RequestMapping("/v3/deviceInfo")
public class DeviceApiV3 extends deviceApiV2 {
    @Resource
    private RedisTemplate stringTemplate;
    @Resource
    private ITblCardDimService ICardService;
    @Resource
    private ITblBuildingDimService IBuildingService;
    @Resource
    private ITblCommDimService ICommService;
    @Resource
    private LocalService localService;
    @Resource
    private AppConfigInfoService appConfigInfoService;
    @Resource
    private OSSClientService ossClientService;
    @Resource
    private LogDevUnlockService logDevUnlockService;

    @RequestMapping("anon/updateCardBlackList")
    @ResponseBody
    public JsonRespData updateCardBlackList(String devAccount, String timeStamp) {
        Long tStamp = (timeStamp == null) ? 0 : Long.valueOf(timeStamp);
        HashOperations<String, String, String> hashOperations = stringTemplate.opsForHash();
        String cachedTimeStamp = hashOperations.get(CardConstant.REDIS_CARD_TIMESTAMP, devAccount);
        Long cachedValue = cachedTimeStamp != null ? Long.valueOf(cachedTimeStamp) : 0;
        /* 假如本地同步时间已经是最新,不再查询 */
        if (tStamp >= cachedValue)
            return new JsonRespData("updateCardBlackList", -1, "没有可更新卡信息！");
        else {
            List<TblCardPerms> list = ICardService.findTblCardsWithTimestamp(devAccount, tStamp, false);
            List<CardPermitInfo> cardPermitList = new ArrayList<>();
            for (TblCardPerms perm : list) {
                CardPermitInfo permitInfo = new CardPermitInfo();
                permitInfo.setCardNo(perm.getCardNo());
                permitInfo.setEnable(perm.getEnable());
                permitInfo.setTimeStamp(perm.getTimeStamp());
                TblCardDimBo cardDimBo = ICardService.findCardInfo(perm.getCardNo());
                permitInfo.setOwnerName(cardDimBo.getOwnerName());
                permitInfo.setRoomName(cardDimBo.getRoomName());
                cardPermitList.add(permitInfo);
            }
            return new JsonRespData("updateCardBlackList", 1, cardPermitList);
        }
    }

    /**
     * 获取设备列表
     *
     * @param Room 帐号
     * @param type
     * @return
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    @RequestMapping("anon/getDevNumber")
    @ResponseBody
    @Override
    public JsonRespData getDevInfoForUser(String Room, String type) throws Exception {
        if (Room.length() != 12 && Room.length() != 4)
            throw new BizException("-1", "getDevNumber", "房号长度不对");

        String comm = Room.substring(0, 4);
        String where = "where 1=1 and comm_code = '" + comm + "'";
        List<TblCommDimBo> comms = ICommService.findTblCommDimByWhere(where);

        switch (type) {
            case "owner": {
                int deviceNumber = IBuildingService.getUnitDevNumber(Room);
                if (deviceNumber < 0)
                    throw new BizException("-1", "getUnitDevNumber", "未查找到数据");
                List<UserDevice> devicesList = new ArrayList<>();
                int manageDevNum = comms.get(0).getManageDevNum();
                for (int i = 0; i < manageDevNum; i++) {
                    String devNum = String.valueOf(i + 1);
                    String sipNum = comm + "0000000" + devNum;
                    devicesList.add(new UserDevice(sipNum, "管理机-" + devNum));
                }
                String stringBuilder = Room.substring(0, 8);
                for (int i = 0; i < deviceNumber; i++) {
                    String devNum = String.valueOf(i + 1);
                    String sipNum = stringBuilder + "000" + devNum;
                    devicesList.add(new UserDevice(sipNum, "门口机-" + devNum));
                }
                int gateDevNum = comms.get(0).getGateDevNum();
                UserDevice devices;
                if (gateDevNum > 0) {
                    for (int i = 0; i < gateDevNum; i++) {
                        devices = new UserDevice();
                        String sipNum = comm + "0000000" + (char) ('a' + i);
                        devices.setAccounts(sipNum);
                        devices.setDisplayName(commUtil.getGateDevAliasName(sipNum, comms.get(0).getGateDevAliasName()));
                        devicesList.add(devices);
                    }
                }
                return new JsonRespData("getDevNumberForOwner", 1, devicesList);
            }
            case "manager":
                List<TblBuildingDimBo> bos = IBuildingService.findTblBuildingDimByWhere(where);
                List<UserDevice> devicesList = new ArrayList<>();
                UserDevice devices;
                for (TblBuildingDimBo tblBuildingDimBo : bos) {
                    String areaName = tblBuildingDimBo.getAreaName();
                    String buildingName = tblBuildingDimBo.getBuildingName();
                    String areaAliasName = tblBuildingDimBo.getAreaAliasName();
                    int devNumber = tblBuildingDimBo.getDevNumber();

                    StringBuilder stringBuilder = new StringBuilder();
                    stringBuilder.append(comm);
                    if (areaName.length() == 1) {
                        stringBuilder.append("0").append(areaName);
                    } else {
                        stringBuilder.append(areaName);
                    }

                    if (buildingName.length() == 1) {
                        stringBuilder.append("0").append(buildingName);
                    } else {
                        stringBuilder.append(buildingName);
                    }

                    for (int i = 0; i < devNumber; i++) {
                        String devNum = String.valueOf(i + 1);
                        String sipNum = stringBuilder.toString() + "000" + devNum;
                        if (StringUtils.isEmpty(areaAliasName)) {
                            devicesList.add(new UserDevice(sipNum, AccountsUtils.getUnitInfo(sipNum) + ":门口机-" + devNum));
                        } else {
                            devicesList.add(new UserDevice(sipNum, areaAliasName + AccountsUtils.getUnit(sipNum) + "单元:门口机-" + devNum));
                        }
                    }
                }
                int gateDevNum = comms.get(0).getGateDevNum();
                if (gateDevNum > 0) {
                    for (int i = 0; i < gateDevNum; i++) {
                        devices = new UserDevice();
                        String sipNum = comm + "0000000" + (char) ('a' + i);
                        devices.setAccounts(sipNum);
                        devices.setDisplayName(commUtil.getGateDevAliasName(sipNum, comms.get(0).getGateDevAliasName()));
                        devicesList.add(devices);
                    }
                }
                return new JsonRespData("getDevNumberForManager", 1, devicesList);
            case "outdoor": {
                DevsNumber info = new DevsNumber();
                info.setGateDevNumber(comms.get(0).getGateDevNum());
                info.setManageDevNumber(comms.get(0).getManageDevNum());

                List<Object[]> list = IBuildingService.findTblBuildingDimBySelectWhere(
                        "select min(CAST(area_name as integer)), sectionName, max(CAST(area_name as integer))",
                        " where 1=1 and comm_code = '" + comm + "'" + " group by section_name order by cast(area_name as int) ASC");
                List<AreaInfo> areaInfos = new ArrayList<>();
                for (Object[] objects : list) {
                    AreaInfo areaInfo = new AreaInfo();
                    areaInfo.setBaseAddr(Integer.valueOf(objects[0].toString()) - 1);
                    areaInfo.setAreaName(objects[1].toString() + "-区");
                    areaInfo.setCount(Integer.valueOf(objects[2].toString()));
                    areaInfos.add(areaInfo);
                }
                info.setAreaInfos(areaInfos);
                return new JsonRespData("getDevNumberForOutdoor", 1, info);
            }
            default:
                throw new BizException("-1", "getDevNumber", "unKnown type");
        }
    }

    @RequestMapping("anon/cardRecord")
    @ResponseBody
    public JsonRespData cardRecord(String cardRecordList, String deviceNum) throws Exception {
        /* 开锁信息写入日志 */
        LogDevUnlock devUnlock;
        List<CardRecord> cardRecords = JSON.parseArray(cardRecordList, CardRecord.class);
        for (CardRecord cRecord : cardRecords) {
            deviceNum = cRecord.getDeviceNum();
            TblCardDimBo cardDimBo = ICardService.findCardInfo(cRecord.getCardNumber());
            if (cardDimBo != null) {
                devUnlock = new LogDevUnlock();
                devUnlock.setCommCode(cardDimBo.getCommCode());
                devUnlock.setBuilding(AccountsUtils.getBuilding(deviceNum));
                devUnlock.setUnit(AccountsUtils.getUnit(deviceNum));
                devUnlock.setDevNumber(deviceNum);
                devUnlock.setOwnerCode(cardDimBo.getOwnerCode());
                devUnlock.setOwnerName(cardDimBo.getOwnerName());
                devUnlock.setRoomInfoNum(cardDimBo.getRoomName());
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String dateString = formatter.format(cRecord.getCardTime());
                devUnlock.setTime(DateUtil.stringDate(dateString));
                devUnlock.setType(DeviceConstant.UNLOCK_TYPE_CARD);
                devUnlock.setMac(cRecord.getMac());
                LogHelper.getLogger(LogConstants.loggerUnlock).debug(GsonUtil.toJson(devUnlock, true), true);
                if (localService.isLanMode()) {
                    devUnlock.setImageUrl(cRecord.getTempFile());
                    logDevUnlockService.saveLogDevUnlockInfo(devUnlock);
                } else {
                    if (StringUtils.isNotEmpty(cRecord.getTempFile())) {
                        String destKey = "outdoor/" + devUnlock.getCommCode() + "/" + cRecord.getTempFile();
                        ossClientService.visitorsCopyFile("temp_1day/" + cRecord.getTempFile(), destKey);
                        devUnlock.setImageUrl(destKey);
                    }
                    LogHelper.getLogger(LogConstants.loggerUnlock).debug(GsonUtil.toJson(devUnlock, true), true);
                }
            }
        }
        return new JsonRespData("cardRecord", 1, null);
    }


    /**
     * 开锁日志实时上传接口
     * @param devUnlocks 开锁记录列表
     * @return
     */
    @RequestMapping("anon/unlockRecord")
    @ResponseBody
   public JsonRespData unlockRecord(@RequestBody LogDevUnlock [] devUnlocks){
        if(devUnlocks.length > 0) {
            for(LogDevUnlock devUnlock : devUnlocks) {
                String deviceNum = devUnlock.getDevNumber();
                if (localService.isLanMode()) {
                    devUnlock.setBuilding(AccountsUtils.getBuilding(deviceNum));
                    devUnlock.setUnit(AccountsUtils.getUnit(deviceNum));
                    devUnlock.setImageUrl(devUnlock.getTempFile());
                    logDevUnlockService.saveLogDevUnlockInfo(devUnlock);
                } else {
                    devUnlock.setBuilding(AccountsUtils.getBuilding(deviceNum));
                    devUnlock.setUnit(AccountsUtils.getUnit(deviceNum));
                    if (StringUtils.isNotEmpty(devUnlock.getTempFile())) {
                        String destKey = "outdoor/" + devUnlock.getCommCode() + "/" + devUnlock.getTempFile();
                        ossClientService.visitorsCopyFile("temp_1day/" + devUnlock.getImageUrl(), destKey);
                        devUnlock.setImageUrl(destKey);
                    }
                    LogHelper.getLogger(LogConstants.loggerUnlock).debug(GsonUtil.toJson(devUnlock, true), true);
                }
            }
            return new JsonRespData("",1,"");
        }
        return new JsonRespData("",-1,"空数据");
    }

    /**
     * 获取门口机，室内机配置
     *
     * @return
     */
    @RequestMapping("anon/getAppConfig")
    @ResponseBody
    public JsonRespData getAppConfig(String deviceType) {
        List<Map> retMaps = new ArrayList<>();
        List<AppConfigInfo> appConfigInfos = appConfigInfoService.queryAppConfigInfoByWhere("where device_type='" + deviceType + "'");
        Map map;
        for (AppConfigInfo appConfigInfo : appConfigInfos) {
            map = new HashMap();
            map.put("id", appConfigInfo.getId());
            map.put("name", appConfigInfo.getName());
            map.put("type", appConfigInfo.getType());
            map.put("description", appConfigInfo.getDescription());
            if (StringUtils.isNotEmpty(appConfigInfo.getContent())) {
                List<AppConfigContentInfo> appConfigContentInfos = JSON.parseArray(appConfigInfo.getContent(), AppConfigContentInfo.class);
                for (AppConfigContentInfo appConfigContentInfo : appConfigContentInfos) {
                    map.put(appConfigContentInfo.getTypeKey(), appConfigContentInfo.getTypeValue());
                }
            }
            retMaps.add(map);
        }
        return new JsonRespData("", 1, retMaps);
    }


    @ResponseBody
    @RequestMapping({"anon/devicesList", "devicesList"})
    public JsonRespData monitorList(String username) throws Exception {
        if (StringUtils.isEmpty(username) || (username.length() != 12 && username.length() != 4))
            throw new BizException("-1", "getDevNumber", "房号长度不对");

        String comm = username.substring(0, 4);
        String where = "where 1=1 and comm_code = '" + comm + "'";
        List<TblCommDimBo> comms = ICommService.findTblCommDimByWhere(where);

        int type = AccountsUtils.devicesType(username);
        switch (type) {
            case DeviceConstant.INDOOR_TYPE: {
                int deviceNumber = IBuildingService.getUnitDevNumber(username);
                if (deviceNumber < 0)
                    throw new BizException("-1", "getUnitDevNumber", "未查找到数据");
                List<UserDevice> devicesList = new ArrayList<>();
                int manageDevNum = comms.get(0).getManageDevNum();
                for (int i = 0; i < manageDevNum; i++) {
                    String devNum = String.valueOf(i + 1);
                    String sipNum = comm + "0000000" + devNum;
                    devicesList.add(new UserDevice(sipNum, "管理机-" + devNum, DeviceConstant.MANAGE_TYPE));
                }
                String stringBuilder = username.substring(0, 8);
                for (int i = 0; i < deviceNumber; i++) {
                    String devNum = String.valueOf(i + 1);
                    String sipNum = stringBuilder + "000" + devNum;
                    devicesList.add(new UserDevice(sipNum, "门口机-" + devNum, DeviceConstant.OUTDOOR_TYPE));
                }
                int gateDevNum = comms.get(0).getGateDevNum();
                UserDevice devices;
                if (gateDevNum > 0) {
                    for (int i = 0; i < gateDevNum; i++) {
                        devices = new UserDevice();
                        String sipNum = comm + "0000000" + (char) ('a' + i);
                        devices.setAccounts(sipNum);
                        devices.setDisplayName(commUtil.getGateDevAliasName(sipNum, comms.get(0).getGateDevAliasName()));
                        devices.setType(DeviceConstant.WALL_TYPE);
                        devicesList.add(devices);
                    }
                }
                return new JsonRespData("", 1, devicesList);
            }
            case DeviceConstant.MANAGE_TYPE:
                List<TblBuildingDimBo> bos = IBuildingService.findTblBuildingDimByWhere(where);
                List<UserDevice> devicesList = new ArrayList<>();
                UserDevice devices;
                for (TblBuildingDimBo tblBuildingDimBo : bos) {
                    String areaName = tblBuildingDimBo.getAreaName();
                    String buildingName = tblBuildingDimBo.getBuildingName();
                    String areaAliasName = tblBuildingDimBo.getAreaAliasName();
                    int devNumber = tblBuildingDimBo.getDevNumber();

                    StringBuilder stringBuilder = new StringBuilder();
                    stringBuilder.append(comm);
                    if (areaName.length() == 1) {
                        stringBuilder.append("0").append(areaName);
                    } else {
                        stringBuilder.append(areaName);
                    }

                    if (buildingName.length() == 1) {
                        stringBuilder.append("0").append(buildingName);
                    } else {
                        stringBuilder.append(buildingName);
                    }

                    for (int i = 0; i < devNumber; i++) {
                        String devNum = String.valueOf(i + 1);
                        String sipNum = stringBuilder.toString() + "000" + devNum;
                        if (StringUtils.isEmpty(areaAliasName)) {
                            devicesList.add(new UserDevice(sipNum, AccountsUtils.getUnitInfo(sipNum) + ":门口机-" + devNum, DeviceConstant.OUTDOOR_TYPE));
                        } else {
                            devicesList.add(new UserDevice(sipNum, areaAliasName + AccountsUtils.getUnit(sipNum) + "单元:门口机-" + devNum, DeviceConstant.OUTDOOR_TYPE));
                        }
                    }
                }
                int gateDevNum = comms.get(0).getGateDevNum();
                if (gateDevNum > 0) {
                    for (int i = 0; i < gateDevNum; i++) {
                        devices = new UserDevice();
                        String sipNum = comm + "0000000" + (char) ('a' + i);
                        devices.setAccounts(sipNum);
                        devices.setDisplayName(commUtil.getGateDevAliasName(sipNum, comms.get(0).getGateDevAliasName()));
                        devices.setType(DeviceConstant.WALL_TYPE);
                        devicesList.add(devices);
                    }
                }
                return new JsonRespData("", 1, devicesList);
            default:
                throw new BizException("-1", "", "未知类型！");
        }
    }

}
